package com.hw.one.collect.spadata.job;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hw.one.collect.client.HttpClient;
import com.hw.one.collect.dust.job.RaiseDustDataJob;
import com.hw.one.collect.dust.redis.BaseRedis;
import com.hw.one.collect.spadata.dao.SpaDataDao;
import com.hw.one.collect.spadata.po.MissData;
import com.hw.one.collect.spadata.po.SpaBaseDataPo;
import com.hw.one.collect.spadata.po.SpaPo;
import com.hw.one.collect.util.HashUtil;
import com.hw.one.collect.util.HttpClientUtil;
import com.hw.one.collect.util.SerializeUtil;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.Serializable;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by Administrator on 2017/8/22.
 */
public class SpaDataJob {
    private static Logger log = Logger.getLogger(SpaDataJob.class);
    // 要抓取的地址
    private static String spaUrl = "http://222.143.40.251:8089/QuerySpaData";
    // 抓取参数中，请求参数，目前是唯一的
    private static String serialNumber = "AT1501G0054S";

    private static String missDataStr = "miss_spa";

    private static String lastDataStr = "last_spa";
    @Resource
    private SpaDataDao spaDataDao;

    @Resource
    private BaseRedis baseRedis;




    /**
     * 保存异常数据
     *
     * @param missData
     */
    public void saveMissData(MissData missData) {
        baseRedis.addObjList(missDataStr, SerializeUtil.ObjTOSerialize(missData));
    }

    /**
     * 删除异常数据
     *
     * @param missData
     */
    public void removeMissData(Serializable missData) {
        baseRedis.deleteSerList(missDataStr, 0, missData);
    }

    /**
     * 取出异常数据
     *
     * @return
     */
    public List<Serializable> getMissData() {
        return baseRedis.getObjList(missDataStr);
    }

    /**
     * 保存最新的一条数据到内存中
     * @param dataObj
     */
    public void saveLastData(Object dataObj) {
        baseRedis.insertSer(lastDataStr, SerializeUtil.ObjTOSerialize(dataObj));
    }

    /**
     * 获取最新的一条数据
     */
    public Serializable getLastData() {
        return baseRedis.getSer(lastDataStr);
    }

    public void saveSpaData(SpaPo spaPo) {
        spaDataDao.saveSpaData(spaPo);

    }

    // 发送请求主方法
    public List<SpaPo> execute(Map<String, String> paramMap) throws ParseException, InterruptedException {
        List<SpaPo> spaPoList = new ArrayList<>();
        // 默认请求5次，请求成功，就跳出循环。
        for (int i=0; i<5; i++) {
            paramMap.put("serialNumber", serialNumber);
            Map<String, String> resultMap = HttpClientUtil.sendPost(spaUrl, new HashMap<String, String>(), paramMap);
            if ("200".equals(resultMap.get("statusCode"))) {
                // 请求成功
                spaPoList = analysisData(resultMap.get("result"));
                break;
            }else {
                Thread.sleep(10000);
            }
        }
        return spaPoList;
    }

    // 解析数据
    private List<SpaPo> analysisData(String jsonStr) throws ParseException {
        JSONObject resultObj = JSONObject.parseObject(jsonStr);
        // PM2.5成分含量
        JSONArray elements = resultObj.getJSONArray("elements");
        // PM2.5颗粒物
        JSONArray sources = resultObj.getJSONArray("sources");
        // 时间
        JSONArray timeElem = resultObj.getJSONArray("timeElem");
        JSONArray timeSrc = resultObj.getJSONArray("timeSrc");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH");
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 创建时间，保持统一，在循环数据之前初始化成一个。
        String createTime = sdf2.format(new Date());
        List<SpaPo> dataList = new ArrayList<>();
        // 循环时间数据,时间数据跟数据是统一的，但是不在一个对象里，循环时间数据时候把需要的集合给初始化好。
        if (timeElem.size() < timeSrc.size()) {
            timeElem = timeSrc;
        }
        for (int i=0; i<timeElem.size(); i++) {
            String timeElemStr = timeElem.getString(i);
            // 替换返回的时间中的汉字
            timeElemStr = timeElemStr.replace("时", "");
            SpaPo spaPo = new SpaPo();
            spaPo.setMONITORTIME(sdf2.format(sdf.parse(timeElemStr)));
            spaPo.setSERIALNUMBER(serialNumber);
            spaPo.setCREATETIME(createTime);
            // 保存到最终的数据集合里
            dataList.add(spaPo);
        }

        // 循环成份含量
        for (int i=0; i<elements.size(); i++) {
            // 解析
            JSONObject element = elements.getJSONObject(i);
            String color = element.getString("color");
            String name = element.getString("name");
            // 数据集合，跟时间集合个数一一对应，循环的时候，需要把上面保存的时间对象拿到然后插入数据
            JSONArray datas = element.getJSONArray("data");
            for (int j=0; j<datas.size(); j++) {
                List<SpaBaseDataPo> elementList = new ArrayList<>();
                SpaBaseDataPo elementObj = new SpaBaseDataPo();
                elementObj.setColor(color);
                elementObj.setName(name);
                elementObj.setData(datas.getString(j));
                elementList.add(elementObj);
                // 此处是判断第一次保存数据的时候还未创建那个数据对象
                if (null == dataList.get(j).getELEMENT()) {
                    dataList.get(j).setELEMENT(elementList);
                }else {
                    // 这里是，如果有了成份含量这个数据，以后的循环是在后面追加。
                    // 循环的j 对应上面时间循环的对象
                    dataList.get(j).getELEMENT().addAll(elementList);
                }
            }
        }
        // 颗粒物数据，跟成份含量数据 一样的流程，只是对象字段不一样
        for (int i=0; i<sources.size(); i++) {
            JSONObject element = sources.getJSONObject(i);
            String color = element.getString("color");
            String name = element.getString("name");
            JSONArray datas = element.getJSONArray("data");
            for (int j=0; j<datas.size(); j++) {
                List<SpaBaseDataPo> elementList = new ArrayList<>();
                SpaBaseDataPo elementObj = new SpaBaseDataPo();
                elementObj.setColor(color);
                elementObj.setName(name);
                elementObj.setData(datas.getString(j));
                elementList.add(elementObj);
                if (null == dataList.get(j).getSOURCES()) {
                    dataList.get(j).setSOURCES(elementList);
                }else {
                    dataList.get(j).getSOURCES().addAll(elementList);
                }
            }
        }
        return dataList;
    }




}
